#ifndef __ENTITY_H__
#define __ENTITY_H__

#include "util/Pool.h"
#include "util/Map.h"

class Packet;
class Request;
class Response;

typedef enum ClockOrder {
    CLOCK_FIRST,

    CLOCK_WITH_PROCESSORS,
    CLOCK_WITH_CACHES,
    CLOCK_WITH_INTERCONNECT,
    CLOCK_WITH_MEMORY,
    CLOCK_WITH_STATISTICS,

    CLOCK_LAST,

    CLOCK_SIZE,
} ClockOrder;

class Entity;

typedef Result (Entity::*PacketHandlerPtr)(Packet*);

class Entity {
  public:
    NEW_DELETE_OPERATORS_H(Entity,NoSuper);
    Entity (const char* name, ClockOrder order);
    virtual ~Entity ();

    virtual Result handle (Packet* r);

    virtual void tick () {};

    char* getName () const {
        return name;
    }

    ClockOrder getClockOrder ();
    void activate ();
    void deactivate ();
    bool onRoute (Entity* dest, Entity* e);

    virtual void addRoute (Entity* src, Entity* dest);
    virtual void deleteRoute (Entity* src);
    virtual Result routePacket (Packet*);

    void ignorePacketType (const std::type_info& type);
    void sinkPacketType (const std::type_info& type);
    
  protected:
    char* name;
    void registerPacketHandler (const std::type_info& type, PacketHandlerPtr);
    
    ClockOrder clockOrder;
    Map<Entity*, Entity*> routes;

    virtual Result sinkFailed (Request* req, Response* resp, Result res);
    Result sinkPacket (Packet* p);
    Result ignorePacket (Packet* p);

  private:
    bool active;
    Map<const std::type_info*, PacketHandlerPtr> dispatchTable;
};

#endif // __ENTITY_H__
